from django.shortcuts import render
from rest_framework.response import Response
from rest_framework.views import APIView
from user.models import User,Address
from goods.models import Goods
from .models import Order,OrderGoods

from django.db import transaction
from django.conf import settings
import datetime,random,redis,os
from alipay import AliPay

# Create your views here.

PUBLIC_URL = open(os.path.join(settings.BASE_DIR,"utils/alipay_secret/alipay_public_key.pem")).read()
PRIVATE_URL = open(os.path.join(settings.BASE_DIR,"utils/alipay_secret/app_private_key.pem")).read()

class MyAliPay(APIView):
    def __init__(self,**kwargs):
        super().__init__(**kwargs)
        self.alipay = AliPay(
            appid='2021000119667016',  #你的支付宝沙箱应用的id
            app_private_key_string=PRIVATE_URL, # 每个人自己的私钥
            alipay_public_key_string=PUBLIC_URL, # 每个人支付宝的公钥
            app_notify_url=None,  # 回调地址
            sign_type='RSA2',  # 签名算法
            debug=True,  # 请求来到支付宝沙箱
        )

    def get_trade_url(self, order_id,total_price):
        """生成下单后支付的地址"""

        order_string = self.alipay.api_alipay_trade_page_pay(
            subject='商家收款',
            out_trade_no=order_id,
            total_amount=total_price,
            return_url='http://127.0.0.1:8000/orders/pay/result/',
            notify_url = None
        )
        return 'https://openapi.alipaydev.com/gateway.do?' + order_string

# 创建订单
class CreateOrder(MyAliPay):
    def post(self,request):
        name = request.data.get('user').get('userName')
        products = request.data.get('products')
        add = request.data.get('addr')
        payMethod = request.data.get('payMethod')
        # 校验
        try:
            user = User.objects.get(username=name)
        except Exception as e:
            return Response({'msg':"用户未登录,请先登录","code":400})
        try:
            address = Address.objects.get(id=add)
        except Exception as e:
            return Response({'msg': "请确认收货地址", "code": 400})
        if payMethod !='1':
            return Response({'msg':"目前仅支持支付宝,其他后续完善","code":400})
        # 创建订单ID，使用时间戳
        order_id = datetime.datetime.now().strftime('%Y%m%d%H%M%S')+str(random.randint(00000000,99999999))+str(user.id)
        # 总数量和总价格
        total_count = 0
        total_amount = 0
        # 开启事务
        with transaction.atomic():
            point = transaction.savepoint()
            try:
                # 创建订单：
                order = Order.objects.create(
                    order_id=order_id,
                    user_id=user.id,
                    address=address,
                    freight=10,
                    pay_method=payMethod,
                    total_amount=total_amount,
                    total_count=total_count,
                )
                for product in products:
                    try:
                        gid = product.get('productID')
                        good = Goods.objects.get(id=int(gid))
                    except Exception as e:
                        return Response({'msg':'该商品已经下架',"code":400})
                    origin_stock = good.stock # 商品库存
                    origin_count = good.count # 销量
                    if product.get('num') > origin_stock:
                        transaction.savepoint_rollback(point)
                        return Response({'msg':"该商品库存不足","code":400})
                    result = Goods.objects.filter(
                        id=product.get('productID'),
                        stock=origin_stock,
                        count=origin_count,
                    )
                    if not result:
                        transaction.savepoint_rollback(point)
                        raise  ValueError('前后数据不一致，创建订单失败')
                    OrderGoods.objects.create(
                        good_id=product.get('productID'),
                        count = product.get('num'),
                        price=product.get('price'),
                        order_id=order_id,
                    )
                    new_stock = origin_stock - product.get('num')
                    new_count = origin_count + product.get('num')
                    good.count = new_count
                    good.stock = new_stock
                    good.save()
                    total_count += product.get('num')
                    total_amount += product.get('price') * product.get('num')
                freiht = 10
                order.total_amount = total_amount + freiht
                order.total_count = total_count
                order.pay_status = 0
                order.save()
            except Exception as e:
                transaction.savepoint_rollback(point)
        rdb = redis.Redis(password='123456')
        cart_key = 'cart_%s'%user.id
        cart_selected = 'cart_selected_%s'%user.id
        for i in products:
            rdb.hdel(cart_key,i.get('productID'))
            rdb.srem(cart_selected,i.get('productID'))
        rdb.close()
        trade_url = self.get_trade_url(order_id,order.total_amount)
        return Response({'msg':"下单成功","code":200,"url":trade_url})

# 给买家和卖家返回响应
class CheckPayResult(MyAliPay):
    def get(self,request):
        """告知买家支付成功"""
        #  获取支付结果的参数
        # 使用query_params 获取支付的结果
        print(request.query_params)
        # 获取订单流水号
        order_id = request.query_params.get('out_trade_no')
        print('>>>>>>>>>>>>>>>',order_id)
        # 根据订单号查询订单的支付结果
        # result = self.alipay.api_alipay_trade_query(out_trade_no=order_id)
        # print('>>>>>>>>>>>>>>>>>>>>',result)
        # if result.get('trade_status') == "TRADE_SUCCESS":
        if order_id:
            # 此时说明支付成功
            # 修改订单的支付状态
            order = Order.objects.get(order_id=order_id)
            # 支付转台是pay_status
            order.pay_status = 1
            order.save()
            # return Response({'msg':"支付成功","code":200})
            return Response({'msg':"支付成功"})
        else:
            return Response({'msg':"支付失败,重新支付"})

    def post(self, request):
        """
        告知卖家支付的结果
        支付宝沙箱没有这功能,只能等项目上线后才能使用,这里仅做说明
        """
        # 把返回的参数形成字典
        data_dict = {k: v for k, v in request.POST.items()}
        # 此时由于项目未上线, 订单的状态修改无效果
        order_id = data_dict.get('out_trade_no')
        # 获取sign
        sign = data_dict.pop('sign')
        # 对sign进行校验,防止伪造
        result = self.alipay.verify(data_dict, sign)
        if result:
            # 此时说明支付成功
            if data_dict.get("trade_status") == "TRADE_SUCCESS":
                # 支付成功
                # 给支付宝的响应
                order = Order.objects.get(order_id=order_id)
                order.pay_method = 1
                order.save()
                return Response({"msg": '支付成功', "code": 200})
            else:
                return Response({"msg": '支付失败', "code": 400})
        else:
            return Response({"msg": "您已经被网警关注", "code": "200"})

# 获取订单信息
class OrderInfo(APIView):
    def post(self,requet):
        username = requet.data.get('user').get('userName')
        try:
            user = User.objects.get(username=username)
        except Exception as e:
            return Response({'msg':"请先登录","code":204})
        orders = user.order.all()
        order_list = []
        for order in orders:
            order_goods = order.orderGood.all()
            temp = []
            for order_good in order_goods:
                temp.append({
                    "productID": order_good.good.id,
                    "productName": order_good.good.sku_name,
                    "productImg": order_good.good.img,
                    "productPrice": order_good.good.price,
                    "productNum": order_good.good.count,
                    "orderID": order.order_id,
                    "createdTime": order.created_time,
                    "payStatus": order.get_pay_status_display()
                })
            order_list.append(temp)
        return Response({"msg":"获取订单数据成功！","code":200,"orders":order_list})

# 去支付
class PayOrder(MyAliPay):
    def post(self,request):
        order_id = request.data.get('orderID')
        total_price = request.data.get('totalPrice')
        url = self.get_trade_url(order_id,total_price)
        return Response({'msg':'去支付','code':302,'pay_url':url})

# 评价
class ChangePayStatusView(APIView):
    def post(self,request):
        order_id = request.data.get('orderID')
        try:
            order = Order.objects.get(order_id=order_id)
            order.pay_status = int(order.pay_status) +1
            order.save()
            return Response({'msg':"修改状态成功","code":200})
        except Exception as e:
            return Response({'msg':"订单不存在","code":400})

# 删除订单或订单商品
class DeleteOrderGoods(APIView):
    def post(self,request):
        order_id = request.data.get('orderID')
        pid = request.data.get('productID')
        try:
            order = Order.objects.get(order_id=order_id)
        except Exception as e:
            return Response({'msg':"订单不存在","code":400})
        # 订单存在, 判断订单中商品的数量
        goods = OrderGoods.objects.all()
        if len(goods) > 1:
            for good in goods:
                if good.id == pid:
                    good.delete()
        else:
            order.delete()
        return Response({'msg':"删除成功","code":200})

